package com.huanhong.hik.socket;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import com.huanhong.hik.service.DeviceService;
import com.huanhong.hik.service.impl.AccessControlServiceImpl;
import io.socket.client.Socket;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * socket 事件处理
 *
 * @author zhls1
 */
@Slf4j
public class EventHandler {

    private static Map<String, DeviceService> deviceServiceMap = new HashMap<>(16);

    private static void accessControl(Object... objects) {
        if (null == objects) {
            return;
        }
        String ip = Convert.toStr(objects[0]);
        String action = Convert.toStr(objects[1]);

        DeviceService deviceService = deviceServiceMap.get(ip);
        if (null == deviceService) {
            deviceService = new AccessControlServiceImpl();
            deviceServiceMap.put(ip, deviceService);
        }
        // 反射执行方法
        Object s;
        if (objects.length > 2) {
            s = ReflectUtil.invoke(deviceService, action, ArrayUtil.sub(objects, 2, objects.length));
        } else {
            s = ReflectUtil.invoke(deviceService, action);
        }

        System.out.println("s:" + s);
    }

    public static void handle(Socket socket) {
        socket.on(Socket.EVENT_CONNECT, args -> socket.send("hello"));
        socket.on(Socket.EVENT_DISCONNECT, args -> log.error(Socket.EVENT_DISCONNECT));
        socket.on(Socket.EVENT_RECONNECT_ATTEMPT, args -> log.error(Socket.EVENT_RECONNECT_ATTEMPT));
        socket.on(Socket.EVENT_RECONNECT_ERROR, args -> log.error(Socket.EVENT_RECONNECT_ERROR));
        socket.on(Socket.EVENT_RECONNECT_FAILED, args -> log.error(Socket.EVENT_RECONNECT_FAILED));
        //自定义事件
        socket.on("borcast", objects -> System.out.println("receive borcast data:" + objects[0].toString()));
        socket.on("connected", objects -> System.out.println("receive connected data:" + objects[0].toString()));
        socket.on("accessControl", EventHandler::accessControl);

        //循环发送数据
        do {
            socket.emit("heartbeat", " heartbeat");
            ThreadUtil.sleep(30000);
        } while (true);
    }
}
